import { assignSaveApi, assignTreeApi } from "@/api/role/role"
import { AssignSaveParm, AssignTreeParm } from "@/api/role/RoleModel"
import { getUserId } from "@/utils/auth"
import { Checked } from "@element-plus/icons-vue"
import { ElTree } from "element-plus"
import { reactive, ref } from "vue"
import useInstance from "@/hooks/useInstance"
export default function useAssignMenu(dialog, onClose, onShow) {
  const { global } = useInstance()
  // ref
  const assignTree = ref<InstanceType<typeof ElTree>>()
  // 树的属性
  const defaultProps = reactive({
    children: 'children',
    label: 'label',
  })
  // 树的数据
  const assignTreeData = reactive({
    list: [],
    assignTreeChecked: [] //原来分配的权限id的集合
  })
  // 定义分配权限的保存参数
  const saveParm = reactive<AssignSaveParm>({
    roleId: '',
    list: []
  })
  // 确定事件
  const confirm = async () => {
    // 选中节点的数据
    let checkedIds = assignTree.value?.getCheckedKeys(false) || []
    // console.log(checkedIds);
    // 半节点的数据
    let hlfIds = assignTree.value?.getHalfCheckedKeys() || []
    // console.log(hlfIds);
    saveParm.list = checkedIds?.concat(hlfIds)
    // 提交保存
    let res = await assignSaveApi(saveParm)
    if (res && res.code == 200) {
      //信息提示
      global.$message({ message: res.msg, type: 'success' })
      //关闭弹框
      onClose()
    }
  }
  // 展示弹窗
  const show = (roleId: string, name: string) => {
    assignTreeData.list = []
    assignTreeData.assignTreeChecked = []
    saveParm.roleId = roleId;
    const parm = {
      roleId: roleId,
      userId: getUserId() || ''
    }
    getAssignTree(parm)
    dialog.height = 420
    dialog.width = 260
    dialog.title = '为【' + name + '】分配权限';

    onShow()
  }
  // 获取树的数据
  const getAssignTree = async (parm: AssignTreeParm) => {
    let res = await assignTreeApi(parm)
    if (res && res.code == 200) {
      //设置权限树数据
      assignTreeData.list = res.data.listmenu
      //设置角色原来的权限Id
      assignTreeData.assignTreeChecked = res.data.checkList
      // 注意这个方法是需要处理一下的，因为目前如果不进行下面的处理
      // 数据返回的是全部选中的节点，包括父级和子级
      // 这里如果把父级的id也返还给他，就会出现这么一种情况
      // 就是这个父级可能有20个权限，其实直选中了其中的一个，
      // 但是由于这个父级的id也在，回显的时候就会把子级的所有选项都选中
      // 这里就需要对获取到的子级的id做一下判断，删除其中的父级id
      if (assignTreeData.assignTreeChecked.length > 0) {
        let newArr = []
        assignTreeData.assignTreeChecked.forEach(item => {
          checked(item, assignTreeData.list, newArr)
        })
        assignTreeData.assignTreeChecked = newArr;
      }
    }
  }
  const checked = (id, data, newArr) => {
    // 这里的id就是拿到的这个角色的权限id(循环出来的)
    // 这个data就是完整的权限树形结构的列表，所有的权限都在这里，就是整个权限的属性结构数据
    data.forEach(item => {
      // 如果这个元素的id和这个传入的id列表中的id一致，那就证明这个元素是目标元素
      // 这个元素本身或者它的子元素中有我们需要的元素
      if (item.id == id) {
        // 如果这个children的长度为零，表明他就是最后一级，把它的id传进去
        // 这里每一级都有id，这个是固定的
        // 这里刻意选中的是最后一级的子级，而不是选中父级节点
        // 因为一旦选中父级，设置了父级，这个父级下面的子级就会全部被选中
        // 通过 (item.children && item.children.length == 0) 这一步，就可以把父级的节点给过滤掉

        // 22年5月7号，再做一些笔记，这里看到了即使是出现了对应的id，也把数据扔掉了
        // 这一点可能会感觉很别扭，但是，这个情景的要求就是第一级符合的，也就是父级id是肯定不能要的
        // 事实上，符合要求的只能是最后一级的id,也就是我们筛选的数据必须同时符合两个条件
        // 1.它的id在给定的id的数组中 通过if (item.id == id)实现
        // 2.它本身是最后一级 通过if (item.children && item.children.length == 0)实现
        // 由此可见，最早符合进入判定的，都会被抛出到else中，只有在ese中再次调用checked函数的,才是符合请求的
        // 这个就类似与递归中只去最后一级的name值的那个情形
        if (item.children && item.children.length == 0) {
          newArr.push(item.id)
        }
      } else {
        // 如果这个id和现有的一级数据的id都不一致，那就继续对二级数据进行循环判定
        // 找到子级 有就继续进行循环
        // 真正需要的子级节点，第一次循环父节点的id肯定对应不上自己的id，会进入到这里
        // 然后就是子级节点的对比，递归调用这个方法
        if (item.children && item.children != 0) {
          checked(id, item.children, newArr)
        }
      }
    });
  }
  return {
    confirm,
    show,
    assignTreeData,
    defaultProps,
    assignTree,
  }
}